# v0.20.0

## 支持新旧mosn之间通过uds转移配置，解决mosn使用xds获取配置无法平滑升级的问题

### config

#### old mosn
```
{
	"inherit_old_mosnconfig" : true,
	"servers":[
		{
			"default_log_path":"stdout",
			"default_log_path":"DEBUG",
			"routers":[
				{
					"router_config_name":"server_router",
					"virtual_hosts":[{
						"name":"serverHost",
						"domains": ["*"],
						"routers": [
							{
								"match":{"prefix":"/"},
								"route":{"cluster_name":"serverCluster"}
							}
						]
					}]
				}
			],
			"listeners":[
				{
					"name":"serverListener",
					"address": "127.0.0.1:2046",
					"bind_port": true,
					"filter_chains": [{
						"filters": [
							{
								"type": "proxy",
								"config": {
									"downstream_protocol": "Http1",
									"upstream_protocol": "Http1",
									"router_config_name":"server_router"
								}
							}
						]
					}]
				}
			]
		}
	],
	"cluster_manager":{
		"clusters":[
			{
				"name":"serverCluster",
				"type": "SIMPLE",
				"lb_type": "LB_RANDOM",
				"max_request_per_conn": 1024,
				"conn_buffer_limit_bytes":32768,
				"hosts":[
					{"address":"127.0.0.1:8080"}
				]
			}
		]
	},
	"admin": {
		"address": {
			"socket_address": {
				"address": "0.0.0.0",
				"port_value": 34902
			}
		}
	}
}
```

#### new mosn

```
{
	"inherit_old_mosnconfig" : true,
	"cluster_manager":{
		"clusters":[
			{
				"name":"serverCluster",
				"type": "SIMPLE",
				"lb_type": "LB_RANDOM",
				"max_request_per_conn": 1024,
				"conn_buffer_limit_bytes":32768,
				"hosts":[
					{"address":"127.0.0.1:8080"}
				]
			}
		]
	},
	"admin": {
		"address": {
			"socket_address": {
				"address": "0.0.0.0",
				"port_value": 34901
			}
		}
	}
}
```

### result

```
2021-01-03 20:31:15,335 [INFO] [server] Get GetInheritConfig start
2021-01-03 20:31:16,335 [INFO] [server] Get GetInheritConfig Accept
2021-01-03 20:31:16,338 [INFO] [cluster] [cluster manager] [AddOrUpdatePrimaryCluster] cluster serverCluster updated
2021-01-03 20:31:16,338 [INFO] [upstream] [host set] update host, final host total: 1
2021-01-03 20:31:16,338 [INFO] [cluster] [primaryCluster] [UpdateHosts] cluster serverCluster update hosts: 1
2021-01-03 20:31:16,338 [INFO] [config] [parse listener] [tcp] inherit listener addr: 127.0.0.1:2046
```

curl localhost:34901/api/v1/config_dump

```
{"mosn_config":{"servers":[{"graceful_timeout":"0s"}],"cluster_manager":{"tls_context":{}},"inherit_old_mosnconfig":true,"tracing":{},"metrics":{"sinks":null,"stats_matcher":{},"shm_zone":"","shm_size":"0B","flush_mosn":false,"lazy_flush":false},"admin":{"address":{"socket_address":{"address":"0.0.0.0","port_value":34901}}},"pprof":{"debug":false,"port_value":0},"plugin":{"log_base":""}},"listener":{"serverListener":{"name":"serverListener","address":"127.0.0.1:2046","bind_port":true,"network":"tcp","filter_chains":[{"tls_context_set":[{}],"filters":[{"type":"proxy","config":{"downstream_protocol":"Http1","router_config_name":"server_router","upstream_protocol":"Http1"}}]}]}},"cluster":{"serverCluster":{"name":"serverCluster","type":"SIMPLE","lb_type":"LB_RANDOM","max_request_per_conn":1024,"conn_buffer_limit_bytes":32768,"circuit_breakers":null,"health_check":{"timeout":"0s","interval":"0s","interval_jitter":"0s"},"spec":{},"lb_subset_config":{},"original_dst_lb_config":{},"tls_context":{},"hosts":[{"address":"127.0.0.1:8080","weight":1}],"dns_resolvers":{}}},"routers":{"server_router":{"router_config_name":"server_router","virtual_hosts":[{"name":"serverHost","domains":["*"],"routers":[{"match":{"prefix":"/"},"route":{"cluster_name":"serverCluster","timeout":"0s"}}]}]}}}
```

## 协议自动识别支持XProtocol

### config

```
{
	"servers":[
		{
			"default_log_path": "stdout",
			"default_log_level":"DEBUG",
			"routers":[
				{
					"router_config_name":"server_router",
					"virtual_hosts":[{
						"name":"serverHost",
						"domains": ["*"],
						"routers": [
							{
								"match":{"prefix":"/"},
								"route":{"cluster_name":"serverCluster"}
							}
						]
					}]
				}
			],
			"listeners":[
				{
					"name":"serverListener",
					"address": "127.0.0.1:2045",
					"bind_port": true,
					"filter_chains": [{
						"filters": [
							{
								"type": "proxy",
								"config": {
									"downstream_protocol": "Auto",
									"upstream_protocol": "Auto",
									"router_config_name":"server_router"
								}
							}
						]
					}]
				}
			]
		}
	],
	"cluster_manager":{
		"clusters":[
			{
				"name":"serverCluster",
				"type": "SIMPLE",
				"lb_type": "LB_RANDOM",
				"max_request_per_conn": 1024,
				"conn_buffer_limit_bytes":32768,
				"hosts":[
					{"address":"127.0.0.1:8080"}
				]
			}
		]
	},
	"admin": {
		"address": {
			"socket_address": {
				"address": "0.0.0.0",
				"port_value": 34902
			}
		}
	}
}
```

go run examples/codes/sofarpc-with-xprotocol-sample/client.go -t

### result

```
2021-01-03 21:06:54,943 [DEBUG] [server] [listener] accept connection from 127.0.0.1:2045, condId= 2, remote addr:127.0.0.1:49597
2021-01-03 21:06:54,943 [DEBUG] [proxy] Protoctol Auto: X
2021-01-03 21:06:54,943 [DEBUG] [2,-] [stream] [xprotocol] new stream detect, requestId = 1
2021-01-03 21:06:54,943 [DEBUG] [2,-] [proxy] [downstream] new stream, proxyId = 1 , requestId =1, oneway=false
2021-01-03 21:06:54,945 [DEBUG] [2,-] [proxy] [downstream] OnReceive headers:&{RequestHeader:{Protocol:1 CmdType:1
```

## 支持广播

### config

mosn_config.json

```
 {
   "servers": [
     {
       "default_log_path": "/dev/stdout",
       "default_log_level": "DEBUG",
       "routers": [
         {
           "router_config_name": "default_router",
           "virtual_hosts": [
             {
               "domains": [
                 "*"
               ],
               "routers": [
                 {
                   "match": {
                     "prefix": "/"
                   },
                   "request_mirror_policies": {
                     "cluster": "defaultCluster",
                     "percent": 100
                   },
                   "route": {
                     "cluster_name": "defaultCluster"
                   }
                 }
               ]
             }
           ]
         }
       ],
       "listeners": [
         {
           "name": "defaultListener",
           "address": "0.0.0.0:2045",
           "bind_port": true,
           "stream_filters": [
             {
               "type": "mirror",
               "config": {
                 "broadcast": true
               }
             }
           ],
           "filter_chains": [
             {
               "filters": [
                 {
                   "type": "proxy",
                   "config": {
                     "downstream_protocol": "Http1",
                     "upstream_protocol": "Http1",
                     "router_config_name": "default_router"
                   }
                 }
               ]
             }
           ]
         }
       ]
     }
   ],
   "cluster_manager": {
     "clusters": [
       {
         "Name": "defaultCluster",
         "type": "EDS",
         "lb_type": "SIMPLE",
         "connect_timeout": "1s",
         "max_request_per_conn": 1024,
         "conn_buffer_limit_bytes": 32768,
         "hosts": [
           {
             "address": "localhost:5302"
           },
           {
             "address": "localhost:5301"
           }
         ]
       }
     ]
   }
 }

```
start server: 
```cassandraql
./server localhost:5301
./server localhost:5302
```
server.go:
```
package main

import (
    "fmt"
    "net/http"
    "os"
)

func ServeHTTP(w http.ResponseWriter, r *http.Request) {
	fmt.Printf("[UPSTREAM]receive request %v", r.Host)
	fmt.Println()

    w.WriteHeader(502)
	w.Header().Set("Content-Type", "text/plain")

	fmt.Fprintf(w, "Method: %s\n", r.Method)
	fmt.Fprintf(w, "ServerAddr: %s\n", os.Args[1])
	fmt.Fprintf(w, "Protocol: %s\n", r.Proto)
	fmt.Fprintf(w, "Host: %s\n", r.Host)
	fmt.Fprintf(w, "RemoteAddr: %s\n", r.RemoteAddr)
	fmt.Fprintf(w, "RequestURI: %q\n", r.RequestURI)
	fmt.Fprintf(w, "URL: %#v\n", r.URL)
	fmt.Fprintf(w, "Body.ContentLength: %d (-1 means unknown)\n", r.ContentLength)
	fmt.Fprintf(w, "Close: %v (relevant for HTTP/1 only)\n", r.Close)
	fmt.Fprintf(w, "TLS: %#v\n", r.TLS)
	fmt.Fprintf(w, "\nHeaders:\n")

	r.Header.Write(w)

}

func main() {
	http.HandleFunc("/", ServeHTTP)
	http.ListenAndServe(os.Args[1], nil)
}
```


### result
curl localhost:2045 -v
```
* Rebuilt URL to: localhost:2045/
*   Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 2045 (#0)
> GET / HTTP/1.1
> Host: localhost:2045
> User-Agent: curl/7.54.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Date: Sun, 03 Jan 2021 13:23:21 GMT
< Content-Length: 0
<
* Connection #0 to host localhost left intact
```
server1:
```
[UPSTREAM]receive request localhost:2045
```
server2:
```
[UPSTREAM]receive request localhost:2045
```


## 支持通过全局配置关闭循环写模式

###  config：

```
{
	"close_graceful" : true,
	"servers":[
		{
			"default_log_path":"stdout",
			"default_log_level": "DEBUG",
			"optimize_local_write": true,
			"routers":[
				{
					"router_config_name":"server_router",
					"virtual_hosts":[{
						"name":"serverHost",
						"domains": ["*"],
						"routers": [
							{
								"match":{"prefix":"/"},
								"route":{"cluster_name":"serverCluster"}
							}
						]
					}]
				}
			],
			"listeners":[
				{
					"name":"serverListener",
					"address": "127.0.0.1:2046",
					"bind_port": true,
					"filter_chains": [{
						"filters": [
							{
								"type": "proxy",
								"config": {
									"downstream_protocol": "Http1",
									"upstream_protocol": "Http1",
									"router_config_name":"server_router"
								}
							}
						]
					}]
				}
			]
		}
	],
	"cluster_manager":{
		"clusters":[
			{
				"name":"serverCluster",
				"type": "SIMPLE",
				"lb_type": "LB_RANDOM",
				"max_request_per_conn": 1024,
				"conn_buffer_limit_bytes":32768,
				"hosts":[
					{"address":"127.0.0.1:8080"}
				]
			}
		]
	},
	"admin": {
		"address": {
			"socket_address": {
				"address": "0.0.0.0",
				"port_value": 34902
			}
		}
	}
}
```

### result

```
2021-01-03 19:05:40,734 [DEBUG] [network] [check use writeloop] Connection = 3, Local Address = 127.0.0.1:63757, Remote Address = 127.0.0.1:8080
2021-01-03 19:05:40,734 [DEBUG] [network] [client connection connect] connect raw tcp, remote address = 127.0.0.1:8080 ,event = ConnectedFlag, error = <nil>
2021-01-03 19:05:40,735 [DEBUG] client OnEvent ConnectedFlag, connected false
```
